/*
* @file    :drv_flash.c
* @module  :FLASH
* @author  :LingFengLu
* @date    :2023-06-06
*/

#include "drv_flash.h"
#include "drv.h"
#include "record.h"
#include "log.h"
#include "lib_string.h"
#include "nvm_db.h"
#include "nvm_db_conf.h"
//Constant definition    宏定义

//Global variable definition    全局变量定义


//Private variable definition    私有变量定义
//Private function declaration   私有函数申明




//Public function definition   公共函数定义
void DrvFlash_Init(void)
{
	BLEPLAT_Init() ;
}

uint DrvFlash_Write
(
uint32 u32_Addr,
uint8 * u8p_Data,
uint32 u32_Len
)
{
	uint32 u32_Data =0;
	uint32 u32_temp_Round = 0 ;
	uint32 u32_temp_remainder = 0 ;
	u32_temp_Round = u32_Len/4 ;
	u32_temp_remainder = u32_Len%4 ;

	if(u32_Addr < FLASH_START_ADDR || u32_Addr > FLASH_END_ADDR)
	{
		LOG_ERROR("DrvFlash_Write: out of range");
		return  FUNCTION_FAIL;
	}
	if((u32_Addr & (FLASH_SIZE_PER_PAGE - 1U)) == 0 )//address is page head
	{
		LL_FLASH_Erase(FLASH, LL_FLASH_TYPE_ERASE_PAGES,((u32_Addr-_MEMORY_FLASH_BEGIN_)/FLASH_SIZE_PER_PAGE),1) ;
		
	}
	for(uint32 i =0 ; i < u32_temp_Round ;i+=1)
	{
		u32_Data = (((uint32)u8p_Data[i*4+3]<<24)|((uint32)u8p_Data[i*4+2]<<16)|((uint32)u8p_Data[i*4+1]<<8)|((uint32)u8p_Data[i*4])) ;
		LL_FLASH_Program(FLASH, u32_Addr, u32_Data) ;
		u32_Addr = u32_Addr + 4 ;
//		LOG_INFO("para1:%x",u32_Data);
	}
	

	u32_Data = 0 ;
	for(uint32 i=0 ; i<u32_temp_remainder ;i++)
	{
		u32_Data |= (uint32)u8p_Data[u32_temp_Round*4+i] << i*8 ;
		
	}
//	LOG_INFO("para2:%x",u32_Data);
	LL_FLASH_Program(FLASH, u32_Addr, u32_Data) ;
	return FUNCTION_OK;
}


uint DrvFlash_Read
(
uint32 u32_Addr,
uint8 * u8p_Data,
uint32 u32_Len
)
{
	if(u32_Addr < FLASH_START_ADDR || u32_Addr > FLASH_END_ADDR)
	{
		LOG_ERROR("DrvFlash_Read: out of range");
		return  FUNCTION_FAIL;
	}
	
	Lib_Memcpy(u8p_Data,(uint8 *)u32_Addr,u32_Len);
	return FUNCTION_OK;
}

uint DrvFlash_ErasePage
(
uint32 u32_Addr
)
{
	LL_FLASH_Erase(FLASH, LL_FLASH_TYPE_ERASE_PAGES,((u32_Addr-_MEMORY_FLASH_BEGIN_)/FLASH_SIZE_PER_PAGE),1) ;
	return FUNCTION_OK;
}

uint DrvFlash_FileLoad
(
uint32 u32_FileID,
uint8 *u8p_Data,
uint32 u32_Length
)
{
	bleplat_nvm_status status =  BLEPLAT_NvmGet( BLEPLAT_NVM_NEXT,
                           u32_FileID,
                           0,
                           u8p_Data,
                           u32_Length )     ; 
	if(status != BLEPLAT_OK)
		return FUNCTION_FAIL  ;
	return FUNCTION_OK  ;
}

uint  DrvFlash_FileWrite
( 
uint32 u32_FileID,
uint8 *u8p_Data,
uint32 u32_Length
)
{
	DrvFlash_DeleteFile(u32_FileID);
	bleplat_nvm_status status =    BLEPLAT_NvmAdd( u32_FileID,
                           u8p_Data,
                           u32_Length,
                           NULL,
                           0 )    ;
	if(status != BLEPLAT_OK)
		return FUNCTION_FAIL  ;
	return FUNCTION_OK  ;
}
uint DrvFlash_DeleteFile
(
uint32 u32_FileID
)
{
	return NVMDB_Erase(u32_FileID) ;
}


#define NVM_TEST_EN   1
#if NVM_TEST_EN==1

#define BUFF_SIZE   100
static uint8 buff1[BUFF_SIZE] = {0} ;
static uint8 readbuff1[BUFF_SIZE] ={0};

static uint8 buff2[BUFF_SIZE] = {0} ;
static uint8 readbuff2[BUFF_SIZE] ={0};

static uint8 buff3[BUFF_SIZE] = {0} ;
static uint8 readbuff3[BUFF_SIZE] ={0};

static uint8 buff4[BUFF_SIZE] = {0} ;
static uint8 readbuff4[BUFF_SIZE] ={0};

static uint8 buff5[BUFF_SIZE] = {0} ;
static uint8 readbuff5[BUFF_SIZE] ={0};

static uint8 buff6[BUFF_SIZE] = {0} ;
static uint8 readbuff6[BUFF_SIZE] ={0};
void NVM_TEST(void)
{
	Lib_Memset( buff1 ,7,BUFF_SIZE) ;
	Lib_Memset( buff2 ,8,BUFF_SIZE) ;
	Lib_Memset( buff3 ,9,BUFF_SIZE) ;
	Lib_Memset( buff4 ,10,BUFF_SIZE) ;
	Lib_Memset( buff5 ,11,BUFF_SIZE) ;
	Lib_Memset( buff6 ,12,BUFF_SIZE) ;

	DrvFlash_FileWrite(RECORD_PAIR_INFO_FILE_ID ,buff1 ,BUFF_SIZE) ;
	DrvFlash_FileWrite(RECORD_SENSOR_PARAM_FILE_ID ,buff2 ,BUFF_SIZE) ;
	DrvFlash_FileWrite(RECORD_HISTORY_HEAD_FILE_ID ,buff3 ,BUFF_SIZE) ;
	DrvFlash_FileWrite(RECORD_CALIB_PARAM_FILE_ID ,buff4 ,BUFF_SIZE) ;
	DrvFlash_FileWrite(RECORD_OPERATE_HEAD_FILE_ID ,buff5 ,BUFF_SIZE) ;
	DrvFlash_FileWrite(RECORD_SETTING_FILE_ID ,buff6 ,BUFF_SIZE) ;
	
	DrvFlash_FileLoad(RECORD_PAIR_INFO_FILE_ID ,readbuff1 ,BUFF_SIZE) ;
	DrvFlash_FileLoad(RECORD_SENSOR_PARAM_FILE_ID ,readbuff2 ,BUFF_SIZE) ;
	DrvFlash_FileLoad(RECORD_HISTORY_HEAD_FILE_ID ,readbuff3 ,BUFF_SIZE) ;
	DrvFlash_FileLoad(RECORD_CALIB_PARAM_FILE_ID ,readbuff4 ,BUFF_SIZE) ;
	DrvFlash_FileLoad(RECORD_OPERATE_HEAD_FILE_ID ,readbuff5 ,BUFF_SIZE) ;
	DrvFlash_FileLoad(RECORD_SETTING_FILE_ID ,readbuff6 ,BUFF_SIZE) ;
	LOG_INFO("readbuff1:\n");
	for(uint16 i=0;i<BUFF_SIZE;i++)
	{
		LOG_INFO("%d",readbuff1[i]);
	}
	LOG_INFO("readbuff2:\n");
	for(uint16 i=0;i<BUFF_SIZE;i++)
	{
		LOG_INFO("%d",readbuff2[i]);
	}
	LOG_INFO("readbuff3:\n");
	for(uint16 i=0;i<BUFF_SIZE;i++)
	{
		LOG_INFO("%d",readbuff3[i]);
	}
	LOG_INFO("readbuff4:\n");
	for(uint16 i=0;i<BUFF_SIZE;i++)
	{
		LOG_INFO("%d",readbuff4[i]);
	}
	LOG_INFO("readbuff5:\n");
	for(uint16 i=0;i<BUFF_SIZE;i++)
	{
		LOG_INFO("%d",readbuff5[i]);
	}
	LOG_INFO("readbuff6:\n");
	for(uint16 i=0;i<BUFF_SIZE;i++)
	{
		LOG_INFO("%d",readbuff6[i]);
	}
}
#endif

//Private function definition   私有函数定义

